/**
 * Created by udi on 2016/11/10.
 */
if (!window.jv) {
  window.jv = {};
}

function MyJson() {
}

/*
 引用该文件后，会自动执行文件最前面的函数 以及 文件最下面的函数。
 */
(function () {
  window.onerror = function (msg, url, lineNo, columnNo, error) {
    var message = [
      'Message: ' + msg,
      'URL: ' + url,
      'Line: ' + lineNo,
      'Column: ' + columnNo,
      'Error object: ' + JSON.stringify(error)
    ].join(' <br /> ');

    document.write(message);
    return true;
  };

  (function () {
    var url = location.search; //获取url中"?"符后的字串
    location.map = {};
    var theRequest = location.map;
    if (url.indexOf("?") > -1) {
      var strs = url.substr(1).split("&");

      for (var i = 0; i < strs.length; i++) {
        theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
      }
    }

    //特殊字段
    location.action = (location.pathname.split("/").filter(function (it) {
      return it;
    }).slice(0, 3).slice(-1)[0] || "").toLowerCase();
    return theRequest;
  })();
  (function () {
    var onResize = function () {
      var i = window.innerWidth; //按 iphone 414/16 = 25.875

      //36px
      if (i > 931.5) {
        i = 931.5;
      }
      return i ? void(document.documentElement.style.fontSize = i / 25.875 + "px") : !1
    }

    window.addEventListener("resize", onResize);
    onResize();
  })();

  //---------------------------------------------------以上是自动执行的部分。

  //简单判断一个对象是否为空 严格意义上的null ， false,0 不算空.
  jv.isNull = function (obj) {
    if (typeof (obj) === "undefined") return true;

    if (obj === null) return true;
    // //既然能传递到这里，那说明一定是有意义的。
    // if (obj === undefined) return true;
    return false;
  }

  //转为布尔值。以下值认为是false: False,false,0,否,假,非
  jv.getBool = function (Value, defValue) {
    ///<param name="Value"></param>
    ///<param name="defValue"></param>

    if (jv.isNull(Value)) return !!defValue;

    if (Value === "False") return false;
    if (Value === "false") return false;
    if (Value == "0") return false;

    if (Value === "否") return false;
    if (Value === "假") return false;
    if (Value === "非") return false;

    return !!Value;
  };

  jv.isString = function (obj) {
    if (obj === "") return true;
    if (!obj) return false;
    return (obj + "") === obj;
  }
  //转为数值型
  jv.getInt = function (Value) {
    ///<summary>转为数值型</summary>
    if (!Value) return 0;

    var ret = parseInt(Value);
    if (ret === 0) return ret;

    return ret || 0;
  };


  jv.logined_refresh = true;
  jv.setToken = function (token) {
    var setCookie = function (name, value, time) {
      var exp = new Date();
      exp.setTime(exp.getTime() + time * 1000);
      document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString() + "; path=/";
    }

    if (token || location.map.token) {
      setCookie("KTOKEN", token || location.map.token, 3600);
      if (token && jv.logined_refresh) {
        window.location = window.location;
      }

      return;
    }
    else if ("token" in location.map) {
      setCookie("KTOKEN", "", -3600);
      setCookie("KSESSION", "", -3600);
    }
  }


  //设置 jv.root , url= jv.root + 根路径
  jv.setUrlPath = function (url) {
    if (!url)return;
    jv.root = location.root = location.pathname.slice(0, location.pathname.toLowerCase().indexOf(url.toLowerCase())) + "/";
    return jv.root;
  }

  jv.defineProperty = function (target, functionName, func, isEnumerable) {
    try {
      if (Object.defineProperty) {
        Object.defineProperty(target, functionName, {value: func, enumerable: isEnumerable || false});
      }
      else {
        target[functionName] = func;
      }
    }
    catch (e) {
      target[functionName] = func;
    }
  };

  jv.defineProperty(String.prototype, 'padLeft', function (Length, Char) {
    var addtional = "";
    for (var i = 0, len = Length - this.length; i < len; i++) {
      addtional += Char;
    }
    return addtional + this;
  });


  jv.defineProperty(String.prototype, 'padRight', function (Length, Char) {
    var addtional = "";
    for (var i = 0, len = Length - this.length; i < len; i++) {
      addtional += Char;
    }
    return this + addtional;
  });

  //保持和C#同样的格式。yyyyMMdd HHmmss
  jv.defineProperty(Date.prototype, 'toString', function () {
    var arg = arguments[0], format = arg;
    if (!format) format = "yyyy-MM-dd";

    var y = this.getFullYear(), m = this.getMonth(), d = this.getDate(), h = this.getHours(), mi = this.getMinutes(), s = this.getSeconds();
    if (y == 1 || (y <= 1901)) return "";

    if (!arg) {
      if (h > 0 || mi > 0 || s > 0) {
        format += " HH:mm";

        if (s > 0) {
          format += ":ss";
        }
      }
    }


    return format.replace(new RegExp("yyyy", "g"), y)
      .replace(new RegExp("MM", "g"), (m + 1).toString().padLeft(2, "0"))
      .replace(new RegExp("dd", "g"), d.toString().padLeft(2, "0"))
      .replace(new RegExp("HH", "g"), h.toString().padLeft(2, "0"))
      .replace(new RegExp("mm", "g"), mi.toString().padLeft(2, "0"))
      .replace(new RegExp("ss", "g"), s.toString().padLeft(2, "0"))
      .replace(new RegExp("yy", "g"), y.toString().slice(2))
      .replace(new RegExp("M", "g"), m + 1)
      .replace(new RegExp("d", "g"), d)
      .replace(new RegExp("hh", "g"), h)
      .replace(new RegExp("m", "g"), mi)
      .replace(new RegExp("s", "g"), s);

  });

  jv.defineProperty(String.prototype, 'formatEx', function () {
    var jsv = arguments[0];
    var sects = arguments[1] || "{}";
    var setEmptyifNo = arguments[2] || false;
    var left = sects[0], right = sects[1];

    return this
      .replace(left + left, String.fromCharCode(7), "g")
      .replace(right + right, String.fromCharCode(8), "g")
      .replace(new RegExp(left + "(\\w+)" + right, "g"),
        //m 是指搜索到的整个部分， 如： {id} , 而 i  是指 该部分的分组内容 ， 如 id
        function (m, i) {
          if (i in jsv) {
            if (jv.isNull(jsv[i])) {
              return "";
            }
            else return jsv[i];
          }
          else if (setEmptyifNo) return "";
          else return m;
        })
      .replace(String.fromCharCode(7), left, "g")
      .replace(String.fromCharCode(8), right, "g")
      ;
  });
//不区分大小写进行查找 other 是数组 返回索引，如果为字典，则返回对应的Key。
  jv.defineProperty(String.prototype, 'indexFrom', function (other) {
    other = other || arguments[0];
    if (!this && !other) return false;
    if (!other) return false;
    var type = jv.getType(other);
    if (type.is("array")) {
      for (var i = 0, len = other.length; i < len; i++) {
        var item = other[i];
        if (this.is(item)) {
          return i;
        }
      }
      return -1;
    }
    else if (type.is("object")) {
      var keys = jv.getJsonKeys(other);
      for (var i = 0, len = keys.length; i < len; i++) {
        var item = keys[i];
        if (this.is(item)) {
          return item;
        }
      }
      return null;
    }
    else if (type.is("string")) {
      if (arguments.length == 1) {
        return other.toLowerCase().indexOf(this.toLowerCase());
      } else {
        //多参
        for (var i = 0, len = arguments.length; i < len; i++) {
          var item = arguments[i];
          if (this.is(item)) {
            return i;
          }
        }
      }
      return -1;
    }

    return false;
  });


//不区分大小写进行比较。
  jv.defineProperty(String.prototype, 'is', function (other) {
    if (!this && !other) return true;
    if (this == other) return true;
    if (!other) return false;
    return this.trim().toLowerCase() == other.trim().toLowerCase();
  });
  jv.getType = function (object) {
    //var _t;
    //return ((_t = typeof (object)) == "object" ? object == null && "null" || Object.prototype.toString.call(object).slice(8, -1) : _t).toLowerCase();

    /*
     Object.prototype.toString.call(object)  和  object + ""  在IE8 下不一样！  Dom对象在前者会返回 [object] or  [object object],而后者返回 [object htmltablerowelement]
     但   Object.prototype.toString.call(object)  和  object + ""  在IE7 下是一样的。
     为了浏览器的一致性。   不返回具体的 类名。
     */
    var _t = (typeof (object)).toLowerCase();
    if (_t == "undefined") return _t;

    if (object === null) {
      return "null";
    }

    if (object instanceof HTMLElement) return "dom";
    if (object instanceof jQuery.Event) return "jQuery.Event";
    if (!jv.isNull(window.XMLHttpRequest) && object instanceof XMLHttpRequest) return "ajax";
    if (!jv.isNull(window.XMLHttpRequestUpload) && object instanceof XMLHttpRequestUpload) return "ajax";
    if (!jv.isNull(window.XMLHttpRequestEventTarget) && object instanceof XMLHttpRequestEventTarget) return "ajax";
    if (!jv.isNull(window.XMLHttpRequestProgressEvent) && object instanceof XMLHttpRequestProgressEvent) return "ajax";

    if (_t == "object") {
      //IE8可能没有 HTMLElement属性。
      //http://www.w3school.com.cn/jsref/dom_obj_all.asp
      //HTML全局属性： class,style ,
      if (object.nodeType && ("class" in object) && ("getAttribute" in object)) return "dom";

      //对于奇皅的IE8来说，  array 在赋值后，可能会变成  object .
      // 如果有 length ,就是 array
      if (jv.msie && "length" in object) return "array";

      _t = Object.prototype.toString.call(object).toLowerCase().slice(8, -1) || _t;
    }

    //借鉴 $.isPlanObject

    return _t;
  };


//判断是否是叶子节点。
  jv.isLeaf = function (node) {
    if (!node) {
      return null;
    }
    var child = node.childNodes;
    var ret = true;
    for (var i = 0, length = child.length; i < length; i++) {
      var n = child[i];
      if (n.nodeType == 8) continue;  //表示 注释comments

      //表示 文本内容
      if (n.nodeType == 3) {
        continue;
      }
      return false;
    }
    return ret;
  };

  jv.findInputs = function (container) {
    var ret = [];

    if (!container) return ret;
    if (container.tagName.indexFrom("input", "textarea", "select") >= 0) {
      ret.push(container);
    }

    var cs = container.getElementsByTagName("input");
    for (var i = 0, length = cs.length; i < length; i++) {
      ret.push(cs[i]);
    }

    cs = container.getElementsByTagName("select");
    for (var i = 0, length = cs.length; i < length; i++) {
      ret.push(cs[i]);
    }

    cs = container.getElementsByTagName("textarea");
    for (var i = 0, length = cs.length; i < length; i++) {
      ret.push(cs[i]);
    }

    return ret;
  };

  jv.isNumberType = function (obj) {
    return obj === +obj;
  };

  jv.isNumber = function (obj) {
    if (jv.isNumberType(obj)) return true;
    if (obj === "0") return true;
    if (!obj) return false;
    obj = obj.trim();
    if (!obj.length) return false;

    for (var i = 0, hasDot = false, len = obj.length; i < len; i++) {
      var code = obj[i].charCodeAt();
      if (code == 46) {              //"." == 46
        if (hasDot == false) {
          hasDot = true;
          continue;
        }
        return false;
      }
      if (code < 48) return false;  //  "0" == 48
      if (code > 57) return false;  //  "9" == 57
    }
    return true;
  }
  jv.bitContains = function (number, containsValue) {
    number = jv.getInt(number);
    containsValue = jv.getInt(containsValue);
    return number & containsValue === containsValue;
  }

  jv.random = function (min, max) {
    if ((min !== 0) && !min && (max !== 0) && !max) {
      return "r" + Math.random().toString(36).slice(3);
    }

    return min + Math.random() * (max - min);
  };

  jv.me = function () {
    return window;
  }

  $.fn.reBind = function (types, data, fn) {
    return this.unbind(types).bind(types, data, fn);
  };

  jv.enumer = function (json) {
    var ret = {};

    ret.getData = function (key) {
      if (key) {
        return json[key];
      }
      return json;
    }

    for (var k in json) {
      ret[k] = k;
    }

    return ret;
  }

  $.fn.getDivJson = function (prefix, option) {
    if ($.isPlainObject(prefix) && !option) {
      option = prefix;
      prefix = "";
    }
    if (prefix !== true) prefix = prefix || "";

    var p = $.extend({
      valueProc: function (val) {
        return (val || "").trim();
      },
      keyProc: function (key) {
        if (!key) return key;

        if (prefix === true) {
          return key.slice(Math.max(key.lastIndexOf("."), key.lastIndexOf("_")) + 1);
        }
        else {
          if (!prefix) return key;
          if (key.indexOf(prefix) != 0) return "";
          return key.slice(prefix.length);
        }
      },
      filter: false, // [contenteditable=true]
      Res: true   //去除 Key  是 _Res 结尾的部分。
    }, option);

    //        var idValues = {}, nameValues = {};
    var jsonVal = new MyJson();

    //keyFunc 表示有key 值 存在时key的回调， valFunc 表示有key值存在时val的回调
    var addVal = function (nameKey, val) {
      var oriValue = jsonVal[nameKey] || [];
      oriValue.push(val);
      jsonVal[nameKey] = oriValue;
    };

    // var setJsonRes = function (nameKey) {
    //     if (!p.Res) return;
    //
    //     // if (!nameKey) return;
    //     // if ( nameKey.endWith("_Res")  ) {
    //     //     var oriIdKey = nameKey.slice(0, - 4);
    //     //     if (oriIdKey in jsonVal) return;
    //     //
    //     //     jsonVal[oriIdKey] = jsonVal[nameKey];
    //     // }
    // }

    var setJsonValue = function (inps) {

      for (var i = 0, length = inps.length; i < length; i++) {
        var c = inps[i];


        var key = c.name || c.id;//|| c.getAttribute("name");

        var nameKey = p.keyProc(key);
        if (!nameKey) continue;

        if (c.tagName == "SELECT") {
          if (c.multiple) {
            var aryKey = nameKey + "_Ary";
            for (var j = 0, ol = c.options.length; j < ol; j++) {
              var op = c.options[j];
              if (op.selected) {
                addVal(nameKey, p.valueProc(op.value));
              }
            }
          }
          else {
            //ie8下是取不到 c.value 的。
            if (c.selectedIndex >= 0) {
              jsonVal[nameKey] = p.valueProc(c.options[c.selectedIndex].getAttribute("value"));
            }
          }

          //setJsonRes(nameKey);
          continue;
        }
        else if (c.tagName == "INPUT") {
          if (c["type"] == "checkbox") {

            if (c.checked) {
              addVal(nameKey, p.valueProc(c.value));
            }
            else {
              if (c.value === "on") {
                jsonVal[nameKey] = "False";
              }
            }
            //setJsonRes(nameKey);
            continue;
          }
          else if (c["type"] == "radio") {
            if (c.checked) {
              jsonVal[nameKey] = p.valueProc(c.value);
            }
            //setJsonRes(nameKey);
            continue;
          }
          else if (nameKey.endsWith("[]")) {
            addVal(nameKey.slice(0, -2), p.valueProc(c.value));
            continue;
          } else {
            //在 .MyDateTime 时，要使用 $.fn.val 方法获取下拉列表里的值。
            //var jc = $(c);
            jsonVal[nameKey] = p.valueProc(c.value);//jc.val());
            //setJsonRes(nameKey);
            continue;
          }

        }
        else if ("BUTTON" == c.tagName) {
          //jsonVal[nameKey] = p.valueProc(c.value);
          //setJsonRes(nameKey);
          continue;
        }
        else if ("TEXTAREA" == c.tagName) {
          jsonVal[nameKey] = p.valueProc($(c).val());
          //setJsonRes(nameKey);
          continue;
        }
        else if (jv.isLeaf(c)) {
          if (nameKey.endsWith("[]")) {
            addVal(nameKey.slice(0, -2), p.valueProc(c.innerHTML));
            continue;
          } else {
            jsonVal[nameKey] = p.valueProc(c.innerHTML);
          }
          //setJsonRes(nameKey);
          continue;
        }
      }
    };


    this.each(function () {
      var inps = jv.findInputs(this);
      //if (p.extDom && p.extDom) {
      //    var extinps = p.extDom();
      //    for (var i = 0; i < extinps.length ; i++) {
      //        inps.push(extinps[i]);
      //    }
      //}

      if (p.filter) {
        inps.addArray($(p.filter));
      }

      //inps.addArray(jv.find("[jsoner=true]"));

      var idInputs = [], nameInputs = [];

      //如果两个都存在， 则优先使用 name.
      $.each(inps, function (i, d) {
        if (d.name) {
          nameInputs.push(d);
        }
        else idInputs.push(d);
      });

      //idInputs = idInputs.minus(nameInputs);

      setJsonValue(idInputs);
      setJsonValue(nameInputs);
    });

    return jsonVal;
  };

  // $.extend只要有属性，则使用该属性。不管值是否是 null 或 undefined
  jv.extend = function () {
    if (!arguments.length)return null;

    var result = arguments[0];

    for (var i = 1; i < arguments.length; i++) {
      var toMerge = arguments[i];

      for (var k in toMerge) {
        var v = toMerge[k];
        if (v === null) continue;
        if (v === undefined) continue;

        result[k] = toMerge[k];
      }
    }
    return result;
  }

  jv.getjQueryValueSelector = function (value) {
    return value.replace(/\./g, "\\.").replace(/\[/g, "\\[").replace(/\]/g, "\\]");
  };
//prefix 前缀，约定： 如果为 true ，表示自动截取 $ _ 最后部分。 否则不截取，默认为 空字符串 表示不截取。
  $.fn.setDivJson = function (JsonValue, prefix, option) {

    if (prefix !== true) prefix = prefix || "";
    var container = this;
    if (container.length == 0) {
      return;
    }
    var p = $.extend({
      refMark: "::",   //1::张三 ,表示设置Id为1，显示的名字是张三。
      clearChecked: true,
      findByName: function (name) {
        if (prefix === true) {
          //优先使用没有前缀的。

          var jObj;
          jObj = $("input[name=" + jv.getjQueryValueSelector(name), container);
          if (jObj.length) return jObj;

          jObj = $("[name$=_" + jv.getjQueryValueSelector(name) + "]", container);
          if (jObj.length) return jObj;
        }
        else {
          if (prefix) {
            name = prefix + name;
          }

          var cons = $("[name=" + jv.getjQueryValueSelector(name) + "]", container);
          if (cons.length > 0) {
            return cons;
          }
          return $();
        }
      },
      findById: function (name) {
        if (prefix === true) {
          //优先使用没有前缀的。

          var jObj;

          jObj = $("#" + jv.getjQueryValueSelector(name), container);
          if (jObj.length) return jObj;

          jObj = $("[name$=_" + jv.getjQueryValueSelector(name) + "]", container);
          if (jObj.length) return jObj;

          return $();
        }
        else {
          if (prefix) {
            name = prefix + name;
          }

          var cons = $("#" + jv.getjQueryValueSelector(name), container);

          if (cons.length > 0) {
            return cons;
          }
          return $();
        }
      }
    }, option);

    var setValue = function (cobj, value) {
      if (!cobj) return;
      var tagName = cobj.tagName;
      if (tagName == "INPUT") {
        var type = cobj["type"];
        if (type.indexFrom("checkbox", "radio") >= 0) {
          //cobj.checked = true;
          return;
        }
        else {
          var self = $(cobj);
          if (value == "0001/01/01 00:00" || value == "0001/1/1 0:00:00") {
            self.val("");
          }
          else {
            //对于 .MyDateTime 来说，要使用 $.fn.val 方法进行设置。
            self.val(value);
          }
          return;
        }
      }
      else if (tagName == "OPTION") {
        cobj.selected = true;
        return;
      }
      else if (tagName == "TEXTAREA" || tagName == "BUTTON") {
        cobj.value = value;
      }
      else if (tagName == "SELECT") {
        $(cobj).val(value);
      }
      else if (tagName == "IMG") {
        cobj.src = value;
      }
      else if (jv.isLeaf(cobj)) {
        cobj.innerHTML = value;
      }
    };

    var setIdValue = function (jobj, value) {
      if (!jobj || !jobj.length) return;
      var cobj = jobj[0];

      return setValue(cobj, value);
    };

    var setNameValue = function (jobj, value) {
      if (!jobj || !jobj.length) return;


      //            var resDom = p.findById(jkey + "_Res");
      //            if (resDom.length) {
      //                setIdValue(resDom, JsonValue[jkey + "_Res"]);
      //            }
      //        }

      var cobj = jobj[0];

      var tagName = cobj.tagName;
      if (tagName == "INPUT") {
        var type = cobj["type"];
        if (type.is("radio")) {
          jobj.filter("[type=radio][value=" + value + "]").prop("checked", true);
          return;
        }
        else if (type.is("checkbox")) {
          //如果 value 是数字，则  1248
          //如果 value 是文本，则 1,2,4,8
          if (jv.isNumber(value)) {
            jobj.each(function () {
              if (jv.bitContains(value, $(this).val())) {
                $(this).prop("checked", true);
              }
              else {
                //如果开始没有清除选中状态的话，现在要清除选中状态。
              }
            });
          }
          else {
            var valueAry = value.split(',');
            if (valueAry.index($(this).val())) {
              $(this).prop("checked", true);
            }
            else {
              //如果开始没有清除选中状态的话，现在要清除选中状态。
            }
          }

        }
      }

      return setValue(cobj, value);
    };

    //清除选中状态。
    if (p.clearChecked) {
      {
        var chks = container[0].getElementsByTagName("input");
        for (var i = 0, length = chks.length; i < length; i++) {
          var n = chks[i];

          if (n.checked) {
            n.checked = false;
          }
        }
      }
      {
        var chks = container[0].getElementsByTagName("select");
        for (var i = 0, length = chks.length; i < length; i++) {
          var n = chks[i];

          n.selectedIndex = -1;
        }
      }
    }


    for (var jkey in JsonValue) {
      //把 $ 替换成 \$ ； 把 # 替换成 \# , 因为它们在 jQuery 选择器中表示特殊的含义 。

      var val = JsonValue[jkey];

      var key = jkey.replace(/\$/g, "\\$").replace(/\#/g, "\\#");

      var leftKIndex = key.indexOf('['), rightKIndex = key.indexOf(']'),
        isCheck = (key.slice(-1) == ']' && (leftKIndex < rightKIndex));
      var checkIndex = -1;
      if (isCheck) {
        checkIndex = parseInt(key.slice(leftKIndex + 1, rightKIndex));
        key = key.slice(0, leftKIndex);
      }

      var cobj = p.findByName(key);

      if (cobj.length) {
        setNameValue(cobj, val);
      }
      else {
        cobj = p.findById(key);
        setIdValue(cobj, val);
      }
    }
    return this;
  };


//标准化插件的初始化。
  jv.initMyPlugin = function (fnName, createFunc) {
    $.fn[fnName] = function (options, param) {
      if (typeof options == 'string') {
        if (!this.length) return;

        var args = [this];
        for (var i = 1; i < arguments.length; i++) {
          args.push(arguments[i]);
        }
        return $.fn[fnName].methods[options].apply(this, args);
      }

      options = options || {};
      return this.each(function () {
        var p = $(this).data(fnName);
        if (p) {
          $.extend(p, options);
        } else {
          p = $.extend({}, $.fn[fnName].defaults, options);
          $(this).data(fnName, p);
        }

        //对于 Boxy 来说，需要知道是谁打开的。
        createFunc.call(this, this, p);
      });
    };
  };


  jv.findTitle = function (oriHtml) {
    var titles = /\<title\>(.*)\<\/title\>/g.exec(oriHtml);
    if (!titles) return "";
    return titles[1] || "";
  };

//判断是否在一个区间，包含等于
  jv.between = function (val, from, to) {
    return (val >= from) && (val <= to);
  }

  jv.getImgNaturalSize = function (img) {
    if (!img) {
      return {};
    }
    if (img.naturalWidth) {
      return {width: img.naturalWidth, height: img.naturalHeight};
    }

    var img = new Image();
    img.src = img.src;
    return {width: img.width, height: img.height};
  }

  jv.error = function (msg) {
    alert(msg);
  }


  jv.post = function (url, data, opt) {
    var defOpt = {
      url: url,
      contentType: "application/json",
      type: "post",
      dataType: "json",
      error: function (xhr, msg) {
        var status = jv.getInt(xhr.getResponseHeader("status"));
        if (status == 590) {
          if (window.android && window.android.login) {
            window.android.login("jv.setToken");
          }
          else {
            document.write("请登录！");
          }
          return;
        }
        var type = xhr.getResponseHeader("content-type");
        var msg = "";
        if (type && (type.indexOf("text/html") > -1)) {
          msg = $(xhr.responseText).filter(function () {
            return this.tagName == "TITLE"
          }).text();
        }
        else if (type && (type.indexOf("text/plain") > -1)) {
          msg = xhr.responseText;
        }

        if (msg) {
          document.body.innerHTML = "<pre class='errorText'>" + msg + "</pre>";
        }
      },
      complete: function (xhr) {
        $(document.documentElement).addClass("loaded").css("animation", "loading 1s");
      }
    };


    if (!opt && $.isFunction(data)) {
      opt = defOpt.success = data;
      data = null;
    }
    else if ($.isFunction(opt)) {
      defOpt.success = opt;
    }
    else {
      $.extend(defOpt, opt);
    }

    defOpt.data = jv.isString(data) ? data : ( data ? JSON.stringify(data) : "");

    return $.ajax(defOpt);
  };


  jv.scroll2Bottom = function (func, triggerOnce) {
    var scrolling = false;
    document.onscroll = function () {
      if (scrolling) return;
      scrolling = true;
      setTimeout(function () {
        var html = document.documentElement;
        var left = html.scrollHeight - html.clientHeight - document.body.scrollTop;
        if (left < 1 || left < 0) { //到达底部100px时,加载新内容
          // 这里加载数据..
          if (func) {
            func();
          }
        }
        scrolling = false;
      }, 300);
    }

    if (triggerOnce && func) {
      func();
    }
  }


  $.fn.showIt = function () {
    this.css("visibility", "visible");
  }

  $.fn.hideIt = function () {
    this.css("visibility", "hidden");
  }


  //----------------------------------------------------------以下是自动执行的部分。
  if (location.map.token) {
    jv.setToken();
  }

  //---------------end
})
();

